<template>
    <div class="top-nav">
        <div class="content pl-4 space-between pr-4">
            <slot name="left">
                <div class="v-center">
                    <!-- 折叠按钮 -->
                    <el-icon @click="reverseMenuFold" class="cursor-pointer icon mr-2" v-if="!showTopMenus || showLeftMenu">
                        <Fold v-if="!menuFolded" />
                        <Expand v-else />
                    </el-icon>

                    <!-- 不展示顶部菜单时，展示当前路由的标题 -->
                    <label v-if="!showTopMenus">{{ title }}</label>
                    <div v-else class="d-flex">
                        <!-- 否则展示顶部菜单 -->

                        <!-- 如果未展示左侧菜单，则需要展示LOGO -->
                        <div class="font-bold title text-center mx-4" v-if="!showLeftMenu">
                            <slot name="logo">
                                <i class="iconfont icon-liushuixian-liushuixianx" />
                            </slot>
                            <span class="ml-2" v-if="!menuFolded">{{ mainTitle }}</span>
                        </div>

                        <div
                            v-for="menu in menus"
                            :key="menu.id"
                            class="top-menu-item v-center mx-2 px-2 cursor-pointer"
                            :class="{ current: currentTopMenu.id == menu.id }"
                            @click="selectTopMenu(menu)"
                        >
                            <ElIcon class="mr-1">
                                <component :is="menu.icon" />
                            </ElIcon>
                            <span>{{ menu.name }}</span>
                        </div>
                    </div>
                </div>
            </slot>

            <div class="v-center mr-4">
                <!-- 站内信 -->
                <el-popover width="400px" trigger="hover" v-if="globalConfig.inboxMsgEnabled != false">
                    <template #reference>
                        <el-badge :value="inboxMsgCount" :hidden="!inboxMsgCount" class="badge mr-4 cursor-pointer">
                            <el-icon size="20px" class="icon"><Bell /></el-icon>
                        </el-badge>
                    </template>

                    <div class="items lh-3 inbox-msg mb-2">
                        <div class="title px-2 py-1">站内信</div>
                        <div>
                            <div v-if="!inboxMsgs.length" class="text-center color-gray mt-4">暂无未读消息</div>
                            <div v-for="msg in inboxMsgs" @click="showInboxMsg(msg)" class="space-between cursor-pointer inbox-msg-item">
                                <div class="msg-title flex-auto">{{ msg.title }}</div>
                                <div class="time-info color-gray font-sm">{{ msg.createTime }}</div>
                            </div>
                        </div>
                        <div class="text-right px-2">
                            <el-link type="primary" @click="moreInboxMsg">更多...</el-link>
                        </div>
                    </div>
                </el-popover>

                <!-- 企业LOGO -->
                <el-image v-if="configInfo.longLogo" :src="configInfo.longLogo" class="logo mr-4" />

                <!-- 用户头像 -->
                <el-avatar v-if="userInfo.photo" :src="userInfo.photo" size="small"></el-avatar>
                <el-avatar class="avatar" v-else :icon="'User'"></el-avatar>

                <!-- 下拉菜单 -->
                <el-dropdown>
                    <label class="cursor-pointer">
                        <span class="ml-2">{{ userInfo.nickname }}</span>
                        <el-icon class="el-icon--right">
                            <arrow-down />
                        </el-icon>
                    </label>
                    <template #dropdown>
                        <el-dropdown-menu>
                            <el-dropdown-item @click="goUserCenter">
                                <el-icon>
                                    <User />
                                </el-icon>
                                <span>个人中心</span>
                            </el-dropdown-item>
                            <el-dropdown-item @click="showUpdatePwd">
                                <el-icon>
                                    <Setting />
                                </el-icon>
                                <span>修改密码</span>
                            </el-dropdown-item>
                            <el-dropdown-item @click="showConfigDialog">
                                <el-icon>
                                    <Operation />
                                </el-icon>
                                <span>布局配置</span>
                            </el-dropdown-item>
                            <el-dropdown-item @click="logout" divided>
                                <el-icon>
                                    <SwitchButton />
                                </el-icon>
                                <span>退出登录</span>
                            </el-dropdown-item>
                        </el-dropdown-menu>
                    </template>
                </el-dropdown>
            </div>
        </div>

        <el-dialog v-model="visible" title="修改密码" width="500px" append-to-body>
            <base-form :fields="fields" v-model="form" ref="formRef" />

            <template #footer>
                <el-button @click="visible = false">取消</el-button>
                <el-button type="primary" @click="updatePassword">确定</el-button>
            </template>
        </el-dialog>

        <el-drawer v-model="configVisible" title="布局配置" size="400px" append-to-body close-on-click-modal>
            <base-form :fields="configFields" v-model="userConfig" ref="configFormRef" />
            <template #footer>
                <el-button @click="configVisible = false">取消</el-button>
                <el-button type="primary" @click="updateConfig">确定</el-button>
            </template>
        </el-drawer>

        <el-drawer v-model="inboxVisible" title="站内信详情" size="500px" append-to-body close-on-click-modal>
            <base-form :fields="inboxFields" v-model="inboxMsg" :readonly="true" labelPosition="top" />
            <template #footer>
                <el-button @click="inboxVisible = false">关闭</el-button>
            </template>
        </el-drawer>
    </div>
</template>

<script setup>
import { onMounted, ref, h, onUnmounted } from "vue";
import { useSysStore } from "../store";
import { useRouter } from "vue-router";
import https from "@/utils/https";
import { ElButton, ElLink, ElMessage } from "element-plus";
import * as _ from "lodash";
import { ElNotification } from "element-plus";
import globalConfig from "@/utils/config.js";

const props = defineProps({
    menus: { type: Array, default: [] },
    title: { type: String },
    mainTitle: { type: String },
});
const sysStore = useSysStore();
const userConfig = ref({});
const menuFolded = defineModel("menuFolded", { default: false });
const currentTopMenu = defineModel("currentMenu", { default: {} });
const userInfo = computed(sysStore.getUserInfo);
const configInfo = computed(sysStore.getSysConfig);
const router = useRouter();
const fields = [
    { label: "原密码", prop: "oldPassword", inputType: "password", required: true },
    { label: "新密码", prop: "password", inputType: "password", required: true },
    { label: "重复新密码", prop: "rePassword", inputType: "password", required: true },
];
const visible = ref(false);
const form = ref({});
const formRef = ref();

const configVisible = ref(false);
const configFields = [
    { label: "显示顶部菜单", prop: "showTopMenus", type: "switch" },
    { label: "多标签模式", prop: "showTagTabs", type: "switch" },
    {
        label: "主题",
        prop: "theme",
        type: "radioGroup",
        options: [
            { label: "默认", value: "default" },
            { label: "暗黑", value: "dark" },
        ],
        change: (val, form) => {
            if (val == "dark") {
                form.menu = "";
            }
        },
    },
    {
        label: "主题色",
        prop: "color",
        type: "radioGroup",
        options: [
            { label: "默认", value: "default" },
            { label: "绿色", value: "green" },
            { label: "红色", value: "red" },
        ],
    },
    {
        label: "左侧菜单色",
        prop: "menu",
        type: "radioGroup",
        display: (form) => {
            return form.theme == "default";
        },
        options: [
            { label: "默认", value: "" },
            { label: "白色", value: "white" },
            { label: "蓝色", value: "blue" },
            { label: "橙色", value: "orange" },
        ],
    },
];
const configFormRef = ref();
const showTopMenus = computed(sysStore.topMenusVisible);
const showLeftMenu = computed(() => {
    return currentTopMenu.value?.children?.length;
});
// 站内信
const inboxMsgs = ref([]);
const inboxMsgCount = ref(0);
const inboxVisible = ref(false);
const inboxFields = [
    { label: "标题", prop: "title" },
    { label: "内容", prop: "content", type: "textarea", rows: 10 },
    { label: "产生时间", prop: "createTime" },
];
const inboxMsg = ref({});

onMounted(() => {
    if (globalConfig.inboxMsgEnabled != false) {
        loadInboxMsg();
    }

    window.websocket.addListener("inboxMsg", processMsg);
});

onUnmounted(() => {
    window.websocket.removeListener("inboxMsg", processMsg);
});

watch(() => router.currentRoute.value.fullPath, refreshTopMenu);
watch(() => props.menus, refreshTopMenu, { deep: true, immediate: true });

/**
 * 刷新顶部菜单
 */
function refreshTopMenu() {
    if (!showTopMenus.value) {
        return;
    }

    // 获取当前选中的顶部菜单
    let path = router.currentRoute.value.path;

    // 有可能是二级界面未配置到菜单中，因此，如果未找到对应的菜单配置，需要找到其上级路由
    let backupMenu;

    let menus = props.menus;
    for (var i in menus) {
        let menu = menus[i];
        if (menu.path == path) {
            currentTopMenu.value = menu;
            return;
        }

        if (menu.children) {
            for (var j in menu.children) {
                let subMenu = menu.children[j];
                if (subMenu.path == path) {
                    currentTopMenu.value = menu;
                    return;
                }
            }
        }

        if (path.startsWith(menu.path)) {
            backupMenu = menu;
        }
    }

    if (backupMenu) {
        currentTopMenu.value = backupMenu;
    } else if (menus.length) {
        // 没找到，选中第一个
        currentTopMenu.value = menus[0];
    }
}

function processMsg(e) {
    ElNotification({
        title: e.title,
        message: h("div", {}, [
            h("div", {}, () => e.content),
            h(
                ElLink,
                {
                    type: "primary",
                    onClick: () => {
                        let id = e.params.id;
                        showInboxMsg({
                            id,
                            title: e.title,
                            content: e.content,
                            createTime: e.time,
                        });
                    },
                },
                () => "查看"
            ),
        ]),
        position: "bottom-right",
    });
    loadInboxMsg();
}

function loadInboxMsg() {
    app.https.post("/sys/inbox-msg/mine", { pageNo: 1, pageSize: 10, status: 0 }).then((resp) => {
        inboxMsgCount.value = resp.total;
        inboxMsgs.value = resp.records;
    });
}

function reverseMenuFold() {
    menuFolded.value = !menuFolded.value;
}

function logout() {
    app.https.get("/auth/logout").then(() => {
        router.push("/login");
    });
}

function showUpdatePwd() {
    visible.value = true;
}

function updatePassword() {
    formRef.value.validate((res) => {
        if (!res) {
            return;
        }

        https.post("/sys/user/update-pwd", form.value).then(() => {
            ElMessage.success("密码更新成功");
            visible.value = false;
        });
    });
}

function selectTopMenu(menu) {
    currentTopMenu.value = menu;

    if (!menu.children.length && menu.path) {
        router.push(menu.path);
    } else if (menu.children.length) {
        router.push(menu.children[0].path);
    }
}

function showConfigDialog() {
    userConfig.value = _.cloneDeep(userInfo.value.metadata || {});
    if (!userConfig.value.showTopMenus && userConfig.value.showTopMenus != false) {
        userConfig.value.showTopMenus = configInfo.value.showTopMenus;
    }

    if (!userConfig.value.showTagTabs && userConfig.value.showTagTabs != false) {
        userConfig.value.showTagTabs = configInfo.value.showTagTabs;
    }

    configVisible.value = true;
}

function updateConfig() {
    app.https
        .post("/sys/user/update-mine", {
            metadata: userConfig.value,
        })
        .then(() => {
            sysStore.setUserInfo({
                ...userInfo.value,
                metadata: userConfig.value,
            });

            configVisible.value = false;

            app.utils.setTheme(userConfig.value.theme, userConfig.value.color, userConfig.value.menu);
        });
}

function moreInboxMsg() {
    router.push("/user/inbox-msg");
}

function showInboxMsg(item) {
    inboxMsg.value = item;
    inboxVisible.value = true;

    app.https.get("/sys/inbox-msg/read", { id: item.id }).then(() => {
        loadInboxMsg();
    });
}

function goUserCenter() {
    router.push("/user/index");
}
</script>

<style lang="scss" scoped>
.top-nav {
    --height: 48px;
    --el-text-color-regular: var(--sub_font_color);

    color: var(--sub_font_color);
    height: var(--height);
    line-height: var(--height);
    background-color: var(--main_bg_color);
    z-index: 4;
    position: relative;

    .content {
        box-shadow: 0 0 4px var(--main_shadow_color);
        height: 100%;
    }

    .icon {
        font-size: 20px;
        color: var(--follow_font_color);
    }

    .avatar {
        font-size: 18px;
        width: 30px;
        height: 30px;
    }
}

:deep() {
    .el-tooltip__trigger {
        outline: unset;
    }
}

.top-menu-item {
    box-sizing: border-box;
    border-bottom: 2px solid transparent;
    transition: transform 0.3s ease;

    &.current {
        border-color: var(--primary_color);
        color: var(--primary_color);
        font-weight: bold;
    }

    &:hover {
        // transform: translateY(2px);
        color: var(--primary_color);
        font-weight: bold;
    }
}

.badge {
    line-height: 1;
}

.inbox-msg {
    .title {
        font-weight: bold;
        border-bottom: 1px solid var(--sub_border_color);
    }

    .inbox-msg-item {
        padding: 0 10px;

        .msg-title {
            text-overflow: ellipsis;
            overflow: hidden;
            white-space: nowrap;
        }

        .time-info {
            min-width: 120px;
            margin-left: 12px;
        }

        &:hover {
            background: var(--primary_color);
            color: #eee;

            .color-gray {
                color: #eee;
            }
        }
    }
}
</style>

<style lang="scss" scoped>
.logo {
    height: 20px;
}
</style>
